﻿#region License
// Copyright 2013 Rolosoft Ltd
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#endregion
namespace Rsft.Net.Dns.Extensions
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics.Contracts;

    internal struct Buffer<TElement>
    {
        internal TElement[] items;
        internal int count;

        internal Buffer(IEnumerable<TElement> source)
        {
            TElement[] array = (TElement[])null;
            int length = 0;
            ICollection<TElement> collection = source as ICollection<TElement>;
            if (collection != null)
            {
                length = collection.Count;
                if (length > 0)
                {
                    array = new TElement[length];
                    collection.CopyTo(array, 0);
                }
            }
            else
            {
                foreach (TElement element in source)
                {
                    if (array == null)
                        array = new TElement[4];
                    else if (array.Length == length)
                    {
                        TElement[] elementArray = new TElement[checked(length * 2)];
                        Array.Copy((Array)array, 0, (Array)elementArray, 0, length);
                        array = elementArray;
                    }
                    array[length] = element;
                    ++length;
                }
            }
            this.items = array;
            this.count = length;
        }

        internal TElement[] ToArray()
        {
            Contract.Requires(((this.count == 0 || this.items.Length == this.count) || this.count <= this.items.Length));

            if (this.count == 0)
                return new TElement[0];
            if (this.items.Length == this.count)
                return this.items;
            TElement[] elementArray = new TElement[this.count];
            Array.Copy((Array)this.items, 0, (Array)elementArray, 0, this.count);
            return elementArray;
        }
    }
}